package cn.edu.thu.laud.jdbc;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import org.apache.cassandra.cql.jdbc.CassandraDriver;
import org.apache.cassandra.cql.jdbc.LaUDCassandraUtils;
import org.apache.cassandra.cql.jdbc.LaUDCassandraUtils.UriProperties;
import org.apache.hadoop.hive.jdbc.HiveDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.edu.thu.laud.jdbc.hivecassandra.HideCassandraDriver;
import cn.edu.thu.laud.jdbc.hivecassandra.HideHiveDriver;

public class LaUDDriver implements Driver {
    public static final int DVR_MAJOR_VERSION = 0;

    public static final int DVR_MINOR_VERSION = 1;

    public static final int DVR_PATCH_VERSION = 0;
    
    public static final String DVR_NAME = "LaUD JDBC Driver";
    
    /**
     * Is this driver JDBC compliant?
     */
    private static final boolean JDBC_COMPLIANT = false;

    /**
     * The required prefix for the connection URL.
     */
    private static final String URL_PREFIX = "jdbc:laud://";
    
    private static final String URL_CASSANDRA_PREFIX=LaUDCassandraUtils.PROTOCOL+"//";

    private static final String URL_HIVE_PREFIX="jdbc:hive://";
    /**
     * If host is provided, without a port.
     */
    private static final String DEFAULT_PORT = "9160";

    /**
     * Property key for the database name.
     */
    private static final String DBNAME_PROPERTY_KEY = "DBNAME";

    /**
     * Property key for the Hive Server host.
     */
    private static final String HOST_PROPERTY_KEY = "HOST";

    /**
     * Property key for the Hive Server port.
     */
    private static final String PORT_PROPERTY_KEY = "PORT";
    
    private static final Logger logger = LoggerFactory.getLogger(LaUDDriver.class);
    
//    private String cassandraURL="";
//    private String hiveURL="";
    
    HideCassandraDriver cassandraDriver;
    HideHiveDriver hiveDriver;
    static{
    	 try {
			java.sql.DriverManager.registerDriver(new LaUDDriver());
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			throw new RuntimeException(e.getMessage());
		}
    	try {
    		
			Class utils=Class.forName("org.apache.cassandra.cql.jdbc.Utils");
			System.out.println(utils.toString());
		
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    	 
    	 
    	 
    }
	@Override
	public boolean acceptsURL(String url) throws SQLException {
		return url.startsWith(URL_PREFIX);
	}

	@Override
	public Connection connect(String url, Properties info) throws SQLException {
		// TODO Auto-generated method stub
		 UriProperties finalProps;
		 String cassandraUrl=url.replaceFirst(URL_PREFIX, URL_CASSANDRA_PREFIX);
		 String hiveUrl=url.replaceFirst(URL_PREFIX, URL_HIVE_PREFIX);
		 
		 
	        if (acceptsURL(url))
	        {
	            // parse the URL into a set of Properties
	            finalProps = LaUDCassandraUtils.parseURL(cassandraUrl,new Properties());
	            // override any matching values in finalProps with values from props
	            finalProps.properties.putAll(info);

	            if (logger.isDebugEnabled()) logger.debug("Final Properties to Connection: {}", finalProps);
	            return new LaUDConnection(finalProps);
	        }
	        else
	        {
	            return null; // signal it is the wrong driver for this protocol:subprotocol
	        }
		 
	}

	@Override
	public int getMajorVersion() {
		return DVR_MAJOR_VERSION;
	}

	@Override
	public int getMinorVersion() {
		return DVR_MINOR_VERSION;
	}

	@Override
	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
			throws SQLException {
		List<DriverPropertyInfo> list=new ArrayList<DriverPropertyInfo>();
		list.addAll(Arrays.asList(cassandraDriver.getPropertyInfo(url, info)));
		list.addAll(Arrays.asList(hiveDriver.getPropertyInfo(url.replaceFirst(URL_PREFIX, URL_HIVE_PREFIX), info)));
		return (DriverPropertyInfo[]) list.toArray();
	}

	@Override
	public boolean jdbcCompliant() {
		return JDBC_COMPLIANT;
	}

	public HiveDriver getHiveDriver(){
		return this.hiveDriver;
	}
	public CassandraDriver getCassandraDriver(){
		return this.cassandraDriver;
	}
}
